#pragma once
#include "util.hpp"
namespace qbe::editing::Clipping {

void clearClippingDisplay(entt::entity& entity, qbe::layout::CellCmd& cmd, layout::CellState& cell_state) {
  if (entity != entt::null) {
    cmd.destroy_entity(entity, true);
    entity = entt::null;
    cell_state = layout::CellState::Render;
  }
}

bool isValidClippingNode(qlib::Cell::s_ptr cell, entt::entity el) {
  if (el == entt::null)
    return false;
  // if (el->getEleLock())
  //   return false;
  auto& reg = cell->reg;
  auto line = reg.try_get<qlib::Path::s_ptr>(el);
  auto polygon = reg.try_get<qlib::Polygon::s_ptr>(el);
  auto ellipse = reg.try_get<qlib::Ellipse::s_ptr>(el);
  auto rectangle = reg.try_get<qlib::Rectangle::s_ptr>(el);
  auto fan = reg.try_get<qlib::Fan::s_ptr>(el);
  if (line) {
    if ((*line)->getLineWidth() == 0) {
      return true;
    } else {
      return false;
    }
  } else {
    return polygon || rectangle || ellipse || fan;
  }
  return true;
}

bool isValidInsNode(qlib::Cell::s_ptr cell, entt::entity el) {
  // if (el->getNodeMask() == NODE_NPICK)
  //   return false;
  // ElememtType t = el->getEleType();
  // if (t == ElememtType::LINE) {
  //   if (dynamic_cast<LineNode*>(el)->m_flexpath->m_elements[0].m_half_width_and_offset.x == 0) {
  //     return true;
  //   } else {
  //     return false;
  //   }
  // } else {
  //   return t == ElememtType::POLYGON || t == ElememtType::ELLIPSE || t == ElememtType::RECTANGLE ||
  //          t == ElememtType::FAN;
  // }

  auto& reg = cell->reg;
  auto line = reg.try_get<qlib::Path::s_ptr>(el);
  auto polygon = reg.try_get<qlib::Polygon::s_ptr>(el);
  auto ellipse = reg.try_get<qlib::Ellipse::s_ptr>(el);
  auto rectangle = reg.try_get<qlib::Rectangle::s_ptr>(el);
  auto fan = reg.try_get<qlib::Fan::s_ptr>(el);
  auto kp = reg.try_get<qlib::KeyPoint::s_ptr>(el);
  if (line) {
    if ((*line)->getLineWidth() == 0) {
      return true;
    } else {
      return false;
    }
  } else {
    return polygon || rectangle || ellipse || fan || kp;
  }
  return true;
}

bool arrayAllEqual(const std::vector<qlib::Vec2d>& array) {
  if (array.size() < 2)
    return true;
  if (array.size() == 2 && (array[0] == array[1] || Extension::distance(array[0], array[1]) < 0.0001))
    return true;
  bool res = true;
  auto first = array[0];
  for (size_t i = 1; i < array.size(); i++) {
    if (first != array[i]) {
      res = false;
      break;
    }
  }
  return res;
}

double distancePointToSegment(const qlib::Vec2d& Q, const qlib::Vec2d& P1, const qlib::Vec2d& P2) {
  // 线段的方向向量
  double dx = P2.x - P1.x;
  double dy = P2.y - P1.y;

  // 点 Q 到线段起点 P1 的向量
  double vx = Q.x - P1.x;
  double vy = Q.y - P1.y;

  // 计算线段长度的平方
  double segmentLengthSq = dx * dx + dy * dy;

  // 如果线段长度为 0，则点到线段起点的距离
  if (segmentLengthSq == 0) {
    return std::sqrt(vx * vx + vy * vy);
  }

  // 计算点到线段的投影比例 t
  double t = (vx * dx + vy * dy) / segmentLengthSq;

  // t 超出 [0, 1] 范围，点最近的点在线段端点之外
  if (t < 0) {
    return std::sqrt(vx * vx + vy * vy);
  } else if (t > 1) {
    double ex = Q.x - P2.x;
    double ey = Q.y - P2.y;
    return std::sqrt(ex * ex + ey * ey);
  }

  // 计算点到线段的最短距离
  double nearestX = P1.x + t * dx;
  double nearestY = P1.y + t * dy;
  double distance = std::sqrt((Q.x - nearestX) * (Q.x - nearestX) + (Q.y - nearestY) * (Q.y - nearestY));
  return distance;
}

bool lineIntersectsAABB2D(qlib::Vec2d& start, qlib::Vec2d& end, qlib::Vec2d& min, qlib::Vec2d& max) {
  // Check if any segment endpoint is inside the AABB
  bool p1Inside = (start.x >= min.x && start.x <= max.x && start.y >= min.y && start.y <= max.y);
  bool p2Inside = (end.x >= min.x && end.x <= max.x && end.y >= min.y && end.y <= max.y);
  if (p1Inside || p2Inside) {
    return true;
  }
  // Check if segment intersects any of the AABB edges
  // Using separating axis theorem (SAT) for AABB vs segment
  double segmentMin, segmentMax;
  // Check x-axis separation
  segmentMin = std::min(start.x, end.x);
  segmentMax = std::max(start.x, end.x);
  if (segmentMax < min.x || segmentMin > max.x) {
    return false;
  }
  // Check y-axis separation
  segmentMin = std::min(start.y, end.y);
  segmentMax = std::max(start.y, end.y);
  if (segmentMax < min.y || segmentMin > max.y) {
    return false;
  }
  return true;  // If no separating axis found, they intersect
}

// 去重并排序函数
std::vector<qlib::Vec2d> uniqueSortedPoints(const std::vector<qlib::Vec2d>& points, const qlib::Vec2d& target) {
  std::set<qlib::Vec2d> uniquePoints(points.begin(), points.end());

  // 转换为 vector
  std::vector<qlib::Vec2d> result(uniquePoints.begin(), uniquePoints.end());

  // 按照距离目标点的距离进行排序
  std::sort(result.begin(), result.end(),
            [&](const qlib::Vec2d& p1, const qlib::Vec2d& p2) { return Extension::distance(p1, target) < Extension::distance(p2, target); });

  return result;
}

//寻找要剪掉的部分
std::vector<qlib::Vec2d> findNearestSegment(qlib::Vec2d& start, qlib::Vec2d& end, std::vector<qlib::Vec2d>& all_intersections,
                                            qlib::Vec2d& target_point) {
  std::vector<qlib::Vec2d> nearestSegment = {start, all_intersections[0]};
  double minDistance = distancePointToSegment(target_point, start, all_intersections[0]);

  for (size_t i = 0; i < all_intersections.size(); i++) {
    int start_index = i;
    int end_index = i + 1;
    qlib::Vec2d s = all_intersections[start_index];
    qlib::Vec2d e;
    if (end_index == all_intersections.size()) {
      e = end;
    } else {
      e = all_intersections[end_index];
    }
    double distance = distancePointToSegment(target_point, s, e);
    if (distance < minDistance) {
      minDistance = distance;
      nearestSegment.clear();
      nearestSegment.push_back(s);
      nearestSegment.push_back(e);
    }
  }

  return nearestSegment;
}

PartCheckedInfo getNearstIntersectEllipse(ClippingData& global, std::vector<entt::entity>& hits, double& min_dist) {
  PartCheckedInfo res;
  auto& reg = global.current_cell->reg;
  for (auto& hit : hits) {
    auto ellipse = reg.try_get<qlib::Ellipse::s_ptr>(hit);
    if (ellipse) {
      auto polygon = (*ellipse)->to_polygon();
      std::vector<qlib::Vec2d> points = polygon->points;
      size_t numVertices = points.size();
      for (size_t i = 0; i < numVertices; ++i) {
        int s = i;
        int e = (i + 1) % numVertices;
        qlib::Vec2d& p1 = points[s];
        qlib::Vec2d& p2 = points[e];  // 循环取下一个点，实现闭合多边形
        double dist = distancePointToSegment(global.mouse_pos, p1, p2);
        if (dist < min_dist) {
          min_dist = dist;
          res.node = hit;
          res.is_ellipse = true;
        }
      }
    }
  }
  return res;
}

PartCheckedInfo getNearstIntersect(ClippingData& global, std::vector<PartCheckedInfo>& hits, double& min_dist) {
  PartCheckedInfo res;
  auto& reg = global.current_cell->reg;
  for (auto& hit : hits) {
    if (hit.indexs.size() == 2) {
      auto line = reg.try_get<qlib::Path::s_ptr>(hit.node);
      if (line) {
        //剪切线的边
        qlib::Vec2d p1 = (*line)->spine.points[hit.indexs[0]];
        qlib::Vec2d p2 = (*line)->spine.points[hit.indexs[1]];
        double dist = distancePointToSegment(global.mouse_pos, p1, p2);
        if (dist < min_dist) {
          min_dist = dist;
          res = hit;
        }
      } else {
        //剪切多边形的边
        auto ellipse = reg.try_get<qlib::Ellipse::s_ptr>(hit.node);
        if (!ellipse) {
          auto polygon = Extension::getPolygon(global.current_cell, hit.node);
          if (polygon) {
            qlib::Vec2d p1 = polygon->points[hit.indexs[0]];
            qlib::Vec2d p2 = polygon->points[hit.indexs[1]];
            double dist = distancePointToSegment(global.mouse_pos, p1, p2);
            if (dist < min_dist) {
              min_dist = dist;
              res = hit;
            }
          }
        }
      }
    }
  }
  return res;
}

void getPreClippingData(ClippingData& global, std::vector<PartCheckedInfo>& pre_hits_part) {
  qlib::Vec2d global_mouse_pos = global.mouse_pos;
  if (global.levelparam.editing_ref_cell) {
    global_mouse_pos = Extension::transOutPoint(global.mouse_pos, global.levelparam);
  }
  double min_dist = 15 / global.axis_scale;
  double w = 15 / global.axis_scale;
  double h = 15 / global.axis_scale;
  double left_min_x = global_mouse_pos.x - w / 2;
  double left_min_y = global_mouse_pos.y - h / 2;
  std::vector<entt::entity> hits_overall = Extension::getQueryEntities(
      global.layout_cmd.query_quad(left_min_x, left_min_y, w, h));  // = LayoutCtrlData::getElementsByBox(left_min_x, left_min_y, w, h);
  PartCheckedInfo preSelectOverallItem = getNearstIntersectEllipse(global, hits_overall, min_dist);  //要操作的圆
  double overall_item_min_dist = min_dist;

  std::vector<PartCheckedInfo> hits_part;  // LayoutCtrlData::getPreSelectedPointLine(global_mouse_pos.x, global_mouse_pos.y);
  PartCheckedInfo preSelectItem = getNearstIntersect(global, pre_hits_part, min_dist);  //要操作的线，多边形及线段
  double part_item_min_dist = min_dist;
  if (preSelectOverallItem.node != entt::null && preSelectItem.node != entt::null) {
    global.preCheckedEl = overall_item_min_dist < part_item_min_dist ? preSelectOverallItem : preSelectItem;  //判断离整体选择还是部分选择的近
  } else if (preSelectOverallItem.node != entt::null) {
    global.preCheckedEl = preSelectOverallItem;
  } else if (preSelectItem.node != entt::null) {
    global.preCheckedEl = preSelectItem;
  } else {
    global.preCheckedEl = PartCheckedInfo();
  }
}

std::vector<ClippingNode> getPreClippingNodes(ClippingData& global) {
  std::vector<std::vector<int>> indexes;
  std::vector<qlib::Vec2d> hit_points;
  std::vector<ClippingNode> res;
  //多选
  if (global.mouse_line && !global.mouse_line->spine.points.empty()) {
    qlib::Vec2d start = global.mouse_line->spine.points[0];
    qlib::Vec2d end = global.mouse_line->spine.points[1];
    std::vector<qlib::Vec2d> box = global.mouse_line->bounding_box();
    if (global.levelparam.editing_ref_cell) {
      //将多选线坐标转换到上层计算顶层包围盒
      qlib::Vec2d start_m = Extension::transOutPoint(start, global.levelparam);
      qlib::Vec2d end_m = Extension::transOutPoint(end, global.levelparam);
      box[0].x = std::min(start_m.x, end_m.x);
      box[0].y = std::min(start_m.y, end_m.y);
      box[1].x = std::max(start_m.x, end_m.x);
      box[1].y = std::max(start_m.y, end_m.y);
    }
    std::vector<entt::entity> nodes = Extension::getQueryEntities(global.layout_cmd.query_quad(
        box[0].x, box[0].y, box[1].x - box[0].x,
        box[1].y - box[0].y));  // = LayoutCtrlData::getElementsByBox(box[0].x, box[0].y, box[1].x - box[0].x, box[1].y - box[0].y);
    qlib::Vec2d ray_start = start;
    qlib::Vec2d ray_dir = end - start;
    if (!nodes.empty()) {
      auto& reg = global.current_cell->reg;
      for (auto node : nodes) {
        if (!isValidClippingNode(global.current_cell, node))
          continue;
        std::vector<qlib::Vec2d> m_obb = Extension::getEntityBoundingBox(global.current_cell, node);
        qlib::Vec2d min(m_obb[0].x, m_obb[0].y);
        qlib::Vec2d max(m_obb[1].x, m_obb[1].y);
        if (!Extension::rayIntersectsAABB2D(ray_start, ray_dir, min, max))
          continue;
        auto line = reg.try_get<qlib::Path::s_ptr>(node);
        bool need_clipping = false;
        if (line) {
          std::vector<qlib::Vec2d>& points = (*line)->spine.points;
          int max = points.size() - 1;
          for (size_t i = 0; i < max; ++i) {
            qlib::Vec2d intersection;  //交点
            int s = i;
            int e = i + 1;
            if (Extension::computeIntersection(start, end, points[s], points[e], intersection)) {
              std::vector<int> idx;
              idx.push_back(s);
              idx.push_back(e);
              indexes.push_back(idx);
              hit_points.push_back(intersection);
              need_clipping = true;
            }
          }
          if (need_clipping) {
            res.push_back(ClippingNode(node, indexes, hit_points));
          }
          indexes.clear();
          hit_points.clear();
        } else {
          auto polygon = Extension::getPolygon(global.current_cell, node);
          if (polygon) {
            std::vector<qlib::Vec2d> points = polygon->points;
            size_t numVertices = points.size();
            for (size_t i = 0; i < numVertices; ++i) {
              int s = i;
              int e = (i + 1) % numVertices;
              qlib::Vec2d& a = points[s];
              qlib::Vec2d& b = points[e];  // 循环取下一个点，实现闭合多边形
              qlib::Vec2d intersection;    //交点
              if (Extension::computeIntersection(start, end, a, b, intersection)) {
                std::vector<int> idx;
                idx.push_back(s);
                idx.push_back(e);
                indexes.push_back(idx);
                hit_points.push_back(intersection);
                need_clipping = true;
              }
            }
            if (need_clipping) {
              res.push_back(ClippingNode(node, indexes, hit_points));
            }
            indexes.clear();
            hit_points.clear();
          }
        }
      }
    }
  } else {
    //单选
    bool is_lock = false;
    if (isValidClippingNode(global.current_cell, global.preCheckedEl.node) &&
        (global.preCheckedEl.indexs.size() >= 2 || global.preCheckedEl.is_ellipse) && !is_lock) {
      indexes.push_back(global.preCheckedEl.indexs);
      hit_points.push_back(global.mouse_pos);
      res.push_back(ClippingNode(global.preCheckedEl.node, indexes, hit_points));
    }
  }
  return res;
}

bool elementIsSelected(ClippingData& global, ClippingNode& target_node) {
  for (auto node : global.overall_selected_nodes) {
    if (target_node.node == node) {
      return true;
    }
  }
  return false;
}

bool elementIsPartSelected(ClippingData& global, ClippingNode& target_node) {
  for (auto& item : global.part_selected_nodes) {
    if (target_node.node == item.node) {
      return true;
    }
  }
  return false;
}

void getPartCheckedLines(ClippingData& global, ClippingNode& target, std::vector<std::vector<int>>& part_checked_lines) {
  for (auto& item : global.part_selected_nodes) {
    if (target.node == item.node) {
      auto& reg = global.current_cell->reg;
      auto fan_node = reg.try_get<qlib::Fan::s_ptr>(target.node);  //选中的扇形
      if (fan_node && item.indexs.size() >= 2) {
        for (size_t i = 0; i < item.indexs.size() - 1; i++) {
          std::vector<int> line_indexs = {item.indexs[i], item.indexs[i + 1]};
          part_checked_lines.push_back(line_indexs);
        }
      } else {
        part_checked_lines.push_back(item.indexs);
      }
    }
  }
}

void getPartCheckedIndexs(ClippingData& global, ClippingNode& target, std::vector<int>& part_checked_indexs) {
  for (auto& item : global.part_selected_nodes) {
    if (target.node == item.node) {
      for (int ind : item.indexs) {
        part_checked_indexs.push_back(ind);
      }
    }
  }
}

void intersectWithPath(qlib::Path::s_ptr target_path, qlib::Path::s_ptr path, qlib::Vec2d& start, qlib::Vec2d& end, int start_index, int end_index,
                       std::vector<qlib::Vec2d>& all_intersections, std::vector<int>& sel_indexs) {
  if (!elementIsVisible(path->layer))
    return;
  std::vector<qlib::Vec2d> points = path->spine.points;
  if (sel_indexs.empty()) {
    if (target_path == path) {
      //和自己对比
      for (size_t i = 0; i < points.size() - 1; ++i) {
        int s = i;
        int e = i + 1;
        //和除开相邻的线段对比
        if ((s >= end_index + 1) || (e <= start_index - 1)) {
          qlib::Vec2d intersection;  //交点
          if (Extension::computeIntersection(start, end, points[i], points[i + 1], intersection)) {
            all_intersections.push_back(intersection);
          }
        }
      }
    } else {
      //和其他线对比
      for (size_t i = 0; i < points.size() - 1; ++i) {
        qlib::Vec2d intersection;  //交点
        if (Extension::computeIntersection(start, end, points[i], points[i + 1], intersection)) {
          all_intersections.push_back(intersection);
        }
      }
    }

    //有宽度的线
    if (target_path != nullptr) {
      if (target_path->width != 0) {
        std::vector<std::shared_ptr<qlib::Polygon>> line_polygons;
        target_path->to_polygons(false, qlib::Tag{0, 0}, line_polygons);
        for (auto polygon : line_polygons) {
          intersectWithPolygon(polygon, start, end, all_intersections, sel_indexs);
        }
      }

      if (path->width != 0) {
        std::vector<std::shared_ptr<qlib::Polygon>> line_polygons;
        path->to_polygons(false, qlib::Tag{0, 0}, line_polygons);
        for (auto polygon : line_polygons) {
          intersectWithPolygon(polygon, start, end, all_intersections, sel_indexs);
        }
      }
    }

  } else {
    //和部分求交
    int s = sel_indexs[0];
    int e = sel_indexs[1];
    if (target_path != path || (s >= end_index + 1) || (e <= start_index - 1)) {
      qlib::Vec2d intersection;  //交点
      if (Extension::computeIntersection(start, end, points[s], points[e], intersection)) {
        all_intersections.push_back(intersection);
      }
    }
  }
}

void intersectWithPolygon(qlib::Polygon::s_ptr polygon, qlib::Vec2d& start, qlib::Vec2d& end, std::vector<qlib::Vec2d>& all_intersections,
                          std::vector<int>& sel_indexs) {
  if (!elementIsVisible(polygon->layer))
    return;
  std::vector<qlib::Vec2d> points = polygon->points;
  if (sel_indexs.empty()) {
    size_t numVertices = points.size();
    for (size_t i = 0; i < numVertices; ++i) {
      qlib::Vec2d& a = points[i];
      qlib::Vec2d& b = points[(i + 1) % numVertices];  // 循环取下一个点，实现闭合多边形
      qlib::Vec2d intersection;                        //交点
      if (Extension::computeIntersection(start, end, a, b, intersection)) {
        all_intersections.push_back(intersection);
      }
    }
  } else {
    qlib::Vec2d& a = points[sel_indexs[0]];
    qlib::Vec2d& b = points[sel_indexs[1]];
    qlib::Vec2d intersection;  //交点
    if (Extension::computeIntersection(start, end, a, b, intersection)) {
      all_intersections.push_back(intersection);
    }
  }
}

void intersectWithKeyPoint(qlib::KeyPoint::s_ptr kp, qlib::Vec2d& start, qlib::Vec2d& end, std::vector<qlib::Vec2d>& all_intersections,
                           std::vector<int>& sel_indexs) {
  if (!elementIsVisible(kp->layer))
    return;
  float epsilon = 1e-6f;
  qlib::Vec2d AB = end - start;         // 向量 AB
  qlib::Vec2d AP = kp->origin - start;  // 向量 AP

  // 1. 检查共线性（叉积 ≈ 0）
  if (abs(Extension::cross_product(AP, AB)) > epsilon) {
    return;  // 不在直线 AB 上
  }

  // 2. 检查 P 是否在 A 和 B 之间（点积和参数 t 判断）
  float dot1 = AP.x * AB.x + AP.y * AB.y;  //AP.dot(AB)
  float dot2 = AB.x * AB.x + AB.y * AB.y;  //AP.dot(AB)
  float t = dot1 / dot2;                   // t [0, 1] 等于0 1 说明在端点
  if (t > -epsilon && t < 1.0f + epsilon) {
    all_intersections.push_back(kp->origin);
  }
}

void intersecPolygontWithPolygon(qlib::Polygon::s_ptr target_polygon, qlib::Polygon::s_ptr polygon, qlib::Vec2d& start, qlib::Vec2d& end,
                                 int start_index, int end_index, std::vector<qlib::Vec2d>& all_intersections, std::vector<int>& sel_indexs,
                                 bool is_same = false) {
  if (!elementIsVisible(polygon->layer))
    return;
  std::vector<qlib::Vec2d> points = polygon->points;
  if (sel_indexs.empty()) {
    size_t numVertices = points.size();
    if (target_polygon == polygon || is_same) {
      //和自己对比
      for (size_t i = 0; i < numVertices; ++i) {
        int s = i;
        int e = (i + 1) % numVertices;
        //和除开相邻的线段对比
        if (s != end_index && s != start_index && e != end_index && e != start_index) {
          qlib::Vec2d intersection;  //交点
          if (Extension::computeIntersection(start, end, points[s], points[e], intersection)) {
            all_intersections.push_back(intersection);
          }
        }
      }
    } else {
      for (size_t i = 0; i < numVertices; ++i) {
        qlib::Vec2d& a = points[i];
        qlib::Vec2d& b = points[(i + 1) % numVertices];  // 循环取下一个点，实现闭合多边形
        qlib::Vec2d intersection;                        //交点
        if (Extension::computeIntersection(start, end, a, b, intersection)) {
          all_intersections.push_back(intersection);
        }
      }
    }

  } else {
    int s = sel_indexs[0];
    int e = sel_indexs[1];
    if (target_polygon == polygon || is_same) {
      //和自己对比
      if (s != end_index && s != start_index && e != end_index && e != start_index) {  //和除开相邻的线段对比
        qlib::Vec2d& a = points[s];
        qlib::Vec2d& b = points[e];
        qlib::Vec2d intersection;  //交点
        if (Extension::computeIntersection(start, end, a, b, intersection)) {
          all_intersections.push_back(intersection);
        }
      }
    } else {
      qlib::Vec2d& a = points[s];
      qlib::Vec2d& b = points[e];
      qlib::Vec2d intersection;  //交点
      if (Extension::computeIntersection(start, end, a, b, intersection)) {
        all_intersections.push_back(intersection);
      }
    }
  }
}

void intersectWithRefer(qlib::Path::s_ptr target_path, qlib::Reference::s_ptr refer, qlib::Vec2d& start, qlib::Vec2d& end, int start_index,
                        int end_index, std::vector<qlib::Vec2d>& all_intersections) {
  qlib::PathPtrArrayMap refer_paths;
  qlib::PolygonPtrArrayMap refer_polygons;
  refer->get_paths(true, -1, false, qlib::Tag{0, 0}, refer_paths);
  refer->get_polygons(true, true, -1, false, qlib::Tag{0, 0}, refer_polygons);

  std::vector<int> empty;
  for (auto layer : refer_paths) {
    for (auto path : layer.second) {
      intersectWithPath(target_path, path, start, end, start_index, end_index, all_intersections, empty);
    }
  }
  for (auto layer : refer_polygons) {
    for (auto polygon : layer.second) {
      intersectWithPolygon(polygon, start, end, all_intersections, empty);
    }
  }
}

void intersectPolygonWithRefer(qlib::Polygon::s_ptr target_polygon, qlib::Reference::s_ptr refer, qlib::Vec2d& start, qlib::Vec2d& end,
                               int start_index, int end_index, std::vector<qlib::Vec2d>& all_intersections) {
  qlib::PathPtrArrayMap refer_paths;
  qlib::PolygonPtrArrayMap refer_polygons;
  refer->get_paths(true, -1, false, qlib::Tag{0, 0}, refer_paths);
  refer->get_polygons(true, true, -1, false, qlib::Tag{0, 0}, refer_polygons);

  std::vector<int> empty;
  for (auto layer : refer_paths) {
    for (auto path : layer.second) {
      intersectWithPath(nullptr, path, start, end, start_index, end_index, all_intersections, empty);
    }
  }
  for (auto layer : refer_polygons) {
    for (auto polygon : layer.second) {
      intersecPolygontWithPolygon(target_polygon, polygon, start, end, start_index, end_index, all_intersections, empty, false);
    }
  }
}

void intersectWithPickedElements(ClippingData& global, qlib::Path::s_ptr target_path, qlib::Vec2d& start, qlib::Vec2d& end, int& start_index,
                                 int& end_index, std::vector<qlib::Vec2d>& all_intersections) {
  std::vector<int> empty;
  for (auto el_nod : global.overall_selected_nodes) {
    if (!isValidInsNode(global.current_cell, el_nod)) {
      continue;
    }
    std::vector<qlib::Vec2d> m_obb = Extension::getEntityBoundingBox(global.current_cell, el_nod);
    qlib::Vec2d min(m_obb[0].x, m_obb[0].y);
    qlib::Vec2d max(m_obb[1].x, m_obb[1].y);
    if (!lineIntersectsAABB2D(start, end, min, max))  //包围盒和线段求交剔除优化
      continue;

    auto& reg = global.current_cell->reg;
    auto line = reg.try_get<qlib::Path::s_ptr>(el_nod);
    auto refer = reg.try_get<qlib::Reference::s_ptr>(el_nod);
    auto kp = reg.try_get<qlib::KeyPoint::s_ptr>(el_nod);
    auto polygon = Extension::getPolygon(global.current_cell, el_nod);
    if (line) {
      intersectWithPath(target_path, *line, start, end, start_index, end_index, all_intersections, empty);
    } else if (refer) {
      // intersectWithRefer(target_path, *refer, start, end, start_index, end_index, all_intersections);
    } else if (polygon) {
      intersectWithPolygon(polygon, start, end, all_intersections, empty);
    } else if (kp) {
      intersectWithKeyPoint(*kp, start, end, all_intersections, empty);
    }
  }
  for (auto s_l : global.part_selected_nodes) {
    if (!isValidInsNode(global.current_cell, s_l.node)) {
      continue;
    }
    std::vector<qlib::Vec2d> m_obb = Extension::getEntityBoundingBox(global.current_cell, s_l.node);
    qlib::Vec2d min(m_obb[0].x, m_obb[0].y);
    qlib::Vec2d max(m_obb[1].x, m_obb[1].y);
    if (!lineIntersectsAABB2D(start, end, min, max))  //包围盒和线段求交剔除优化
      continue;
    auto& reg = global.current_cell->reg;
    auto line = reg.try_get<qlib::Path::s_ptr>(s_l.node);
    if (line) {
      intersectWithPath(target_path, *line, start, end, start_index, end_index, all_intersections, s_l.indexs);
    } else {
      auto ellipse = reg.try_get<qlib::Ellipse::s_ptr>(s_l.node);
      auto fan = reg.try_get<qlib::Fan::s_ptr>(s_l.node);
      //对圆的部分选择做处理 提取边框求交
      if (ellipse) {
        std::vector<qlib::Vec2d> border_points = s_l.key_points;  //边框顶点
        // for (auto& pos : s_l.node->getBoxKeyPoints()) {
        //   border_points.push_back(Vec2(pos.x(), pos.y()));
        // }
        qlib::Polygon::s_ptr polygon = qlib::Polygon::create();
        polygon->layer = (*ellipse)->layer;
        polygon->points = border_points;
        intersectWithPolygon(polygon, start, end, all_intersections, s_l.indexs);
      } else if (fan) {
        auto polygon = Extension::getPolygon(global.current_cell, s_l.node);
        for (size_t i = 0; i < s_l.indexs.size() - 1; i++) {
          std::vector<int> line_indexs = {s_l.indexs[i], s_l.indexs[i + 1]};
          intersectWithPolygon(polygon, start, end, all_intersections, line_indexs);
        }
      } else {
        auto polygon = Extension::getPolygon(global.current_cell, s_l.node);
        intersectWithPolygon(polygon, start, end, all_intersections, s_l.indexs);
      }
    }
  }
}

std::vector<entt::entity> getIntersectNodes(ClippingData& global, qlib::Vec2d& start, qlib::Vec2d& end) {
  qlib::Vec2d min, max;
  qlib::Vec2d start_m = start;
  qlib::Vec2d end_m = end;
  if (global.levelparam.editing_ref_cell) {
    start_m = Extension::transOutPoint(start, global.levelparam);
    end_m = Extension::transOutPoint(end, global.levelparam);
  }
  min.x = std::min(start_m.x, end_m.x);
  min.y = std::min(start_m.y, end_m.y);
  max.x = std::max(start_m.x, end_m.x);
  max.y = std::max(start_m.y, end_m.y);
  min.x -= 0.1;
  min.y -= 0.1;
  max.x += 0.1;
  max.y += 0.1;                               //扩大包围盒搜索
  double w = std::max(max.x - min.x, 0.001);  //长宽为0的时候查询不出来
  double h = std::max(max.y - min.y, 0.001);
  std::vector<entt::entity> nodes = Extension::getQueryEntities(
      global.layout_cmd.query_quad(min.x, min.y, w, h));  // = LayoutCtrlData::getElementsByBox(min.x, min.y, w, h);  //包围盒所有相交
  return nodes;
}

void getPathSplitLines(ClippingData& global, qlib::Path::s_ptr target_path, std::vector<qlib::Vec2d>& points, std::vector<SplitLineInfo>& split_lines,
                       std::vector<qlib::Vec2d>& clipping_inters, bool& exist_inter, int index_prefix) {
  std::vector<qlib::Vec2d> split_line;  //分解的线
  qlib::Vec2d before_inter_pos = qlib::Vec2d(9999999, 9999999);
  int spl_start_index = 0 + index_prefix;  //分解线起始索引
  int spl_end_index = 0;                   //分解线起始索引
  bool head_is_inters = false;             //有交点线段的结尾段第一个点
  for (size_t i = 0; i < points.size() - 1; ++i) {
    std::vector<qlib::Vec2d> all_intersections;  //所有交点
    int start_index = i;
    int end_index = i + 1;
    qlib::Vec2d start = points[start_index];
    qlib::Vec2d end = points[end_index];
    int real_start_index = start_index + index_prefix;
    int real_end_index = end_index + index_prefix;
    intersectWithPickedElements(global, target_path, start, end, real_start_index, real_end_index,
                                all_intersections);  //与选中的可交对象求交点

    all_intersections = uniqueSortedPoints(all_intersections, start);
    // line_all_intersections.push_back(all_intersections);
    for (auto pos : all_intersections) {
      if (pos != before_inter_pos) {
        clipping_inters.push_back(pos);
      }
      clipping_inters.push_back(pos);
    }
    // segment_inter_infos.push_back(SegmentInterInfo(start_index, all_intersections));
    if (!all_intersections.empty()) {
      exist_inter = true;
    }
    spl_end_index = real_end_index;

    if (all_intersections.empty()) {
      //没有交点记录所有点
      split_line.push_back(start);
      split_line.push_back(end);
    } else {
      split_line.push_back(start);
      int max = all_intersections.size();
      for (size_t j = 0; j < max; j++) {
        if (j == 0) {
          split_line.push_back(all_intersections[j]);
          split_lines.push_back(SplitLineInfo(split_line, spl_start_index, spl_end_index, false, true));
          split_line.clear();
          spl_start_index = real_start_index;
        } else {
          split_line.push_back(all_intersections[j - 1]);
          split_line.push_back(all_intersections[j]);
          split_lines.push_back(SplitLineInfo(split_line, spl_start_index, spl_end_index, true, true));
          split_line.clear();
          spl_start_index = real_start_index;
        }
      }
      split_line.push_back(all_intersections[max - 1]);
      split_line.push_back(end);
      head_is_inters = true;
      if (end_index == points.size() - 1) {
        split_lines.push_back(SplitLineInfo(split_line, spl_start_index, spl_end_index, head_is_inters, false));
        split_line.clear();
        spl_start_index = real_start_index;
        head_is_inters = false;
      }
    }
    if (end_index == points.size() - 1 && !split_line.empty() && split_line.size() > 1) {
      split_lines.push_back(SplitLineInfo(split_line, spl_start_index, spl_end_index, head_is_inters, false));
      spl_start_index = real_start_index;
      head_is_inters = false;
    }
  }
}

void getPathParCheckedSplitLines(ClippingData& global, qlib::Path::s_ptr target_path, std::vector<qlib::Vec2d>& points,
                                 std::vector<std::vector<int>>& checked_lines_index, std::vector<SplitLineInfo>& split_lines,
                                 std::vector<qlib::Vec2d>& clipping_inters, bool& exist_inter) {
  std::vector<std::vector<qlib::Vec2d>> split_by_part_check_lines;  //先根据部分选中的线分解整条线
  std::vector<qlib::Vec2d> split_line;                              //分解的线
  int before_index = -1;
  int before_picked = false;
  bool before_checked = false;
  for (size_t i = 0; i < points.size() - 1; ++i) {
    int start_index = i;
    int end_index = i + 1;
    bool now_checked;
    auto it = std::find_if(checked_lines_index.begin(), checked_lines_index.end(),
                           [start_index, end_index](const std::vector<int>& e) { return e[0] == start_index && e[1] == end_index; });
    if (it != checked_lines_index.end()) {
      now_checked = true;
    } else {
      now_checked = false;
    }
    if (now_checked == before_checked) {
      if (before_index == start_index) {
        split_line.push_back(points[end_index]);
      } else {
        split_line.push_back(points[start_index]);
        split_line.push_back(points[end_index]);
      }
    } else {
      if (!split_line.empty()) {
        split_by_part_check_lines.push_back(split_line);
        split_line.clear();
      }
      split_line.push_back(points[start_index]);
      split_line.push_back(points[end_index]);
    }

    before_checked = now_checked;
    before_index = end_index;
  }

  if (!split_line.empty()) {
    split_by_part_check_lines.push_back(split_line);
  }
  int index_prefix = 0;
  for (auto& split_line_points : split_by_part_check_lines) {
    getPathSplitLines(global, target_path, split_line_points, split_lines, clipping_inters, exist_inter, index_prefix);
    index_prefix += split_line_points.size() - 1;
  }
}

void intersectPolygonWithPickedElements(ClippingData& global, entt::entity target_entt, qlib::Polygon::s_ptr target_polygon, qlib::Vec2d& start,
                                        qlib::Vec2d& end, int& start_index, int& end_index, std::vector<qlib::Vec2d>& all_intersections) {
  std::vector<int> empty;
  for (auto el_nod : global.overall_selected_nodes) {
    if (!isValidInsNode(global.current_cell, el_nod)) {
      continue;
    }
    std::vector<qlib::Vec2d> m_obb = Extension::getEntityBoundingBox(global.current_cell, el_nod);
    qlib::Vec2d min(m_obb[0].x, m_obb[0].y);
    qlib::Vec2d max(m_obb[1].x, m_obb[1].y);
    if (!lineIntersectsAABB2D(start, end, min, max))  //包围盒和线段求交剔除优化
      continue;
    auto& reg = global.current_cell->reg;
    auto line = reg.try_get<qlib::Path::s_ptr>(el_nod);
    auto refer = reg.try_get<qlib::Reference::s_ptr>(el_nod);
    auto polygon = Extension::getPolygon(global.current_cell, el_nod);
    bool is_same = target_entt == el_nod;
    if (line) {
      intersectWithPath(nullptr, *line, start, end, start_index, end_index, all_intersections, empty);
    } else if (refer) {
      intersectPolygonWithRefer(target_polygon, *refer, start, end, start_index, end_index, all_intersections);
    } else if (polygon) {
      intersecPolygontWithPolygon(target_polygon, polygon, start, end, start_index, end_index, all_intersections, empty, is_same);
    }
  }
  for (auto s_l : global.part_selected_nodes) {
    if (!isValidInsNode(global.current_cell, s_l.node)) {
      continue;
    }
    std::vector<qlib::Vec2d> m_obb = Extension::getEntityBoundingBox(global.current_cell, s_l.node);
    qlib::Vec2d min(m_obb[0].x, m_obb[0].y);
    qlib::Vec2d max(m_obb[1].x, m_obb[1].y);
    if (!lineIntersectsAABB2D(start, end, min, max))  //包围盒和线段求交剔除优化
      continue;
    auto& reg = global.current_cell->reg;
    auto line = reg.try_get<qlib::Path::s_ptr>(s_l.node);
    if (line) {
      intersectWithPath(nullptr, *line, start, end, start_index, end_index, all_intersections, s_l.indexs);
    } else {
      auto ellipse = reg.try_get<qlib::Ellipse::s_ptr>(s_l.node);
      auto fan = reg.try_get<qlib::Fan::s_ptr>(s_l.node);
      auto polygon = Extension::getPolygon(global.current_cell, s_l.node);
      bool is_same = target_entt == s_l.node;
      //对圆的部分选择做处理 提取边框求交
      if (ellipse) {
        std::vector<qlib::Vec2d> border_points = s_l.key_points;
        // for (auto& pos : s_l.node->getBoxKeyPoints()) {
        //   border_points.push_back(Vec2(pos.x(), pos.y()));
        // }
        qlib::Polygon::s_ptr polygon = qlib::Polygon::create();
        polygon->layer = (*ellipse)->layer;
        polygon->points = border_points;
        intersecPolygontWithPolygon(target_polygon, polygon, start, end, start_index, end_index, all_intersections, s_l.indexs, is_same);
      } else if (fan) {
        for (size_t i = 0; i < s_l.indexs.size() - 1; i++) {
          std::vector<int> line_indexs = {s_l.indexs[i], s_l.indexs[i + 1]};
          intersecPolygontWithPolygon(target_polygon, polygon, start, end, start_index, end_index, all_intersections, line_indexs, is_same);
        }
      } else if (polygon) {
        intersecPolygontWithPolygon(target_polygon, polygon, start, end, start_index, end_index, all_intersections, s_l.indexs, is_same);
      }
    }
  }
}

void getPolygonPathSplitLines(ClippingData& global, entt::entity target_entt, qlib::Polygon::s_ptr target_polygon, std::vector<qlib::Vec2d>& points,
                              std::vector<SplitLineInfo>& split_lines, std::vector<qlib::Vec2d>& clipping_inters, bool& exist_inter,
                              std::vector<int>& real_indexs) {
  std::vector<qlib::Vec2d> split_line;       //分解的线
  int spl_start_index = 0 + real_indexs[0];  //分解线起始索引
  int spl_end_index = 0;                     //分解线起始索引
  bool head_is_inters = false;               //有交点线段的结尾段第一个点
  for (size_t i = 0; i < points.size() - 1; ++i) {
    std::vector<qlib::Vec2d> all_intersections;  //所有交点
    int start_index = i;
    int end_index = i + 1;
    qlib::Vec2d start = points[start_index];
    qlib::Vec2d end = points[end_index];
    int real_start_index = real_indexs[start_index];
    int real_end_index = real_indexs[end_index];
    intersectPolygonWithPickedElements(global, target_entt, target_polygon, start, end, real_start_index, real_end_index,
                                       all_intersections);  //与选中的可交对象求交点

    all_intersections = uniqueSortedPoints(all_intersections, start);
    // line_all_intersections.push_back(all_intersections);
    for (auto pos : all_intersections) {
      clipping_inters.push_back(pos);
    }
    // segment_inter_infos.push_back(SegmentInterInfo(start_index, all_intersections));
    if (!all_intersections.empty()) {
      exist_inter = true;
    }
    spl_end_index = real_end_index;
    if (all_intersections.empty()) {
      //没有交点记录所有点
      split_line.push_back(start);
      split_line.push_back(end);
    } else {
      split_line.push_back(start);
      int max = all_intersections.size();
      for (size_t j = 0; j < max; j++) {
        if (j == 0) {
          split_line.push_back(all_intersections[j]);
          split_lines.push_back(SplitLineInfo(split_line, spl_start_index, spl_end_index, false, true));
          split_line.clear();
          spl_start_index = real_start_index;
        } else {
          split_line.push_back(all_intersections[j - 1]);
          split_line.push_back(all_intersections[j]);
          split_lines.push_back(SplitLineInfo(split_line, spl_start_index, spl_end_index, true, true));
          split_line.clear();
          spl_start_index = real_start_index;
        }
      }
      split_line.push_back(all_intersections[max - 1]);
      split_line.push_back(end);
      head_is_inters = true;
      if (end_index == points.size() - 1) {
        split_lines.push_back(SplitLineInfo(split_line, spl_start_index, spl_end_index, head_is_inters, false));
        split_line.clear();
        spl_start_index = real_start_index;
        head_is_inters = false;
      }
    }
    if (end_index == points.size() - 1 && !split_line.empty() && split_line.size() > 1) {
      split_lines.push_back(SplitLineInfo(split_line, spl_start_index, spl_end_index, head_is_inters, false));
      spl_start_index = real_start_index;
      head_is_inters = false;
    }
  }
}

void getPolygonParCheckedSplitLines(ClippingData& global, entt::entity target_entt, qlib::Polygon::s_ptr target_polygon,
                                    std::vector<qlib::Vec2d>& points, std::vector<std::vector<int>>& checked_lines_index,
                                    std::vector<SplitLineInfo>& split_lines, std::vector<qlib::Vec2d>& clipping_inters, bool& exist_inter) {
  std::vector<std::vector<qlib::Vec2d>> split_by_part_check_lines;  //先根据部分选中的线分解整个多边形
  std::vector<std::vector<int>> split_by_part_check_lines_indexs;   //分解线的下标
  std::vector<qlib::Vec2d> split_line;                              //分解的线
  std::vector<int> split_line_indexs;                               //分解的线的多边形下标
  int before_index = -1;
  int before_picked = false;
  bool before_checked = false;
  size_t numVertices = points.size();
  bool first_line_is_checked = false;
  bool last_line_is_checked = false;
  for (size_t i = 0; i < numVertices; ++i) {
    int start_index = i;
    int end_index = (i + 1) % numVertices;
    bool now_checked;
    auto it = std::find_if(checked_lines_index.begin(), checked_lines_index.end(),
                           [start_index, end_index](const std::vector<int>& e) { return e[0] == start_index && e[1] == end_index; });
    if (it != checked_lines_index.end()) {
      now_checked = true;
    } else {
      now_checked = false;
    }
    if (start_index == 0 && now_checked) {
      first_line_is_checked = true;  //标记第一条线选中状态
    }
    if (end_index == 0 && now_checked) {
      last_line_is_checked = true;  //标记最后一条线选中状态
    }
    if (now_checked == before_checked) {
      if (before_index == start_index) {
        split_line.push_back(points[end_index]);
        split_line_indexs.push_back(end_index);
      } else {
        split_line.push_back(points[start_index]);
        split_line.push_back(points[end_index]);
        split_line_indexs.push_back(start_index);
        split_line_indexs.push_back(end_index);
      }
    } else {
      if (!split_line.empty()) {
        split_by_part_check_lines.push_back(split_line);
        split_by_part_check_lines_indexs.push_back(split_line_indexs);
        split_line.clear();
        split_line_indexs.clear();
      }
      split_line.push_back(points[start_index]);
      split_line.push_back(points[end_index]);
      split_line_indexs.push_back(start_index);
      split_line_indexs.push_back(end_index);
    }

    before_checked = now_checked;
    before_index = end_index;
  }

  if (!split_line.empty()) {
    //首尾选择状态相同
    if (first_line_is_checked == last_line_is_checked) {
      auto& first_line_array = split_by_part_check_lines[0];
      split_line.pop_back();                               //移除最后一个点
      std::reverse(split_line.begin(), split_line.end());  //逆转顺序
      first_line_array.insert(first_line_array.begin(), split_line.rbegin(), split_line.rend());

      auto& first_line_array_indexs = split_by_part_check_lines_indexs[0];
      split_line_indexs.pop_back();
      std::reverse(split_line_indexs.begin(), split_line_indexs.end());  //逆转顺序
      first_line_array_indexs.insert(first_line_array_indexs.begin(), split_line_indexs.rbegin(), split_line_indexs.rend());
    } else {
      split_by_part_check_lines.push_back(split_line);
      split_by_part_check_lines_indexs.push_back(split_line_indexs);
    }
  }
  int i = 0;
  for (auto& split_line_points : split_by_part_check_lines) {
    getPolygonPathSplitLines(global, target_entt, target_polygon, split_line_points, split_lines, clipping_inters, exist_inter,
                             split_by_part_check_lines_indexs[i]);
    i++;
  }
}

void intersectPolygonWithAll(ClippingData& global, entt::entity target_entt, qlib::Polygon::s_ptr target_polygon, qlib::Vec2d& start,
                             qlib::Vec2d& end, int& start_index, int& end_index, std::vector<qlib::Vec2d>& all_intersections) {
  std::vector<int> empty;
  std::vector<entt::entity> hits = getIntersectNodes(global, start, end);  //需要四叉树查询剔除优化比对对象
  for (auto el_nod : hits) {
    if (!isValidInsNode(global.current_cell, el_nod)) {
      continue;
    }
    auto& reg = global.current_cell->reg;
    auto line = reg.try_get<qlib::Path::s_ptr>(el_nod);
    auto refer = reg.try_get<qlib::Reference::s_ptr>(el_nod);
    auto polygon = Extension::getPolygon(global.current_cell, el_nod);
    if (line) {
      intersectWithPath(nullptr, *line, start, end, start_index, end_index, all_intersections, empty);
    } else if (refer) {
      intersectPolygonWithRefer(target_polygon, *refer, start, end, start_index, end_index, all_intersections);
    } else if (polygon) {
      bool is_same = target_entt == el_nod;
      intersecPolygontWithPolygon(target_polygon, polygon, start, end, start_index, end_index, all_intersections, empty, is_same);
    }
  }
}

void getPolygonSplitLines(ClippingData& global, entt::entity target_entt, qlib::Polygon::s_ptr target_polygon, std::vector<qlib::Vec2d>& points,
                          std::vector<SplitLineInfo>& split_lines, std::vector<qlib::Vec2d>& clipping_inters, bool& exist_inter, bool insert_all) {
  std::vector<qlib::Vec2d> split_line;  //分解的线
  int spl_start_index = 0;              //分解线起始索引
  int spl_end_index = 0;                //分解线起始索引
  size_t numVertices = points.size();
  qlib::Vec2d before_inter_pos = qlib::Vec2d(9999999, 9999999);
  for (size_t i = 0; i < numVertices; ++i) {
    std::vector<qlib::Vec2d> all_intersections;  //所有交点
    int start_index = i;
    int end_index = (i + 1) % numVertices;
    qlib::Vec2d start = points[start_index];
    qlib::Vec2d end = points[end_index];
    int real_start_index = start_index;
    int real_end_index = end_index;
    if (insert_all) {
      intersectPolygonWithAll(global, target_entt, target_polygon, start, end, real_start_index, real_end_index,
                              all_intersections);  //与所有的可交对象求交点
    } else {
      intersectPolygonWithPickedElements(global, target_entt, target_polygon, start, end, real_start_index, real_end_index,
                                         all_intersections);  //与选中的可交对象求交点
    }

    all_intersections = uniqueSortedPoints(all_intersections, start);
    for (auto pos : all_intersections) {
      if (pos != before_inter_pos) {
        clipping_inters.push_back(pos);
        before_inter_pos = pos;
      }
    }
    if (!all_intersections.empty()) {
      exist_inter = true;
    }
    spl_end_index = end_index;
    if (all_intersections.empty()) {
      //没有交点记录所有点
      split_line.push_back(start);
      split_line.push_back(end);
    } else {
      split_line.push_back(start);
      int max = all_intersections.size();
      for (size_t j = 0; j < max; j++) {
        if (j == 0) {
          split_line.push_back(all_intersections[j]);
          split_lines.push_back(SplitLineInfo(split_line, spl_start_index, spl_end_index));
          split_line.clear();
          spl_start_index = start_index;
        } else {
          split_line.push_back(all_intersections[j - 1]);
          split_line.push_back(all_intersections[j]);
          split_lines.push_back(SplitLineInfo(split_line, spl_start_index, spl_end_index));
          split_line.clear();
          spl_start_index = start_index;
        }
      }
      split_line.push_back(all_intersections[max - 1]);
      split_line.push_back(end);
      if (end_index == 0) {
        //末尾
        auto& first_line_array = split_lines[0].points;
        std::reverse(split_line.begin(), split_line.end());  //逆转顺序
        first_line_array.insert(first_line_array.begin(), split_line.rbegin(), split_line.rend());
        split_line.clear();
        spl_start_index = start_index;
      }
    }
    if (end_index == 0 && !split_line.empty() && split_line.size() > 1) {
      //末尾
      if (!split_lines.empty()) {
        auto& first_line_array = split_lines[0].points;
        std::reverse(split_line.begin(), split_line.end());  //逆转顺序
        first_line_array.insert(first_line_array.begin(), split_line.rbegin(), split_line.rend());
      }
    }
  }
}

double getLineDistWithPoint(const std::vector<qlib::Vec2d>& points, qlib::Vec2d& target_point) {
  double min_dist = distancePointToSegment(target_point, points[0], points[1]);
  if (points.size() > 2) {
    for (size_t i = 1; i < points.size() - 1; i++) {
      double dist = distancePointToSegment(target_point, points[i], points[i + 1]);
      if (dist < min_dist) {
        min_dist = dist;
      }
    }
  }
  return min_dist;
}

std::vector<qlib::Vec2d> getClippingLineWithTarget(std::vector<SplitLineInfo>& split_lines, qlib::Vec2d& target_point) {
  std::vector<qlib::Vec2d> res;
  double min_dist = getLineDistWithPoint(split_lines[0].points, target_point);
  res = split_lines[0].points;
  int remove_index = 0;
  if (split_lines.size() > 1) {
    for (size_t i = 1; i < split_lines.size(); i++) {
      double dist = getLineDistWithPoint(split_lines[i].points, target_point);
      if (dist < min_dist) {
        min_dist = dist;
        res = split_lines[i].points;
        remove_index = i;
      }
    }
  }
  split_lines[remove_index].need_remove = true;
  return res;
}

std::vector<std::vector<int>> getElementPartSelectIndexs(ClippingData& global, entt::entity target) {
  std::vector<std::vector<int>> res;
  for (auto& item : global.part_selected_nodes) {
    if (target == item.node && item.indexs.size() > 1) {
      auto& reg = global.current_cell->reg;
      auto fan = reg.try_get<qlib::Fan::s_ptr>(target);
      if (fan && item.indexs.size() >= 2) {
        for (size_t i = 0; i < item.indexs.size() - 1; i++) {
          std::vector<int> line_indexs = {item.indexs[i], item.indexs[i + 1]};
          res.push_back(line_indexs);
        }
      } else {
        res.push_back(item.indexs);
      }
    }
  }
  return res;
}

void intersectWithAll(ClippingData& global, qlib::Path::s_ptr target_path, qlib::Vec2d& start, qlib::Vec2d& end, int& start_index, int& end_index,
                      std::vector<qlib::Vec2d>& all_intersections) {
  std::vector<int> empty;
  std::vector<entt::entity> hits = getIntersectNodes(global, start, end);  //需要四叉树查询剔除优化比对对象
  for (auto el_nod : hits) {
    if (!isValidInsNode(global.current_cell, el_nod)) {
      continue;
    }
    auto& reg = global.current_cell->reg;
    auto line = reg.try_get<qlib::Path::s_ptr>(el_nod);
    auto refer = reg.try_get<qlib::Reference::s_ptr>(el_nod);
    auto kp = reg.try_get<qlib::KeyPoint::s_ptr>(el_nod);
    auto polygon = Extension::getPolygon(global.current_cell, el_nod);
    if (line) {
      intersectWithPath(target_path, *line, start, end, start_index, end_index, all_intersections, empty);
    } else if (refer) {
      // intersectWithRefer(target_path, *refer, start, end, start_index, end_index, all_intersections);
    } else if (polygon) {
      intersectWithPolygon(polygon, start, end, all_intersections, empty);
    } else if (kp) {
      intersectWithKeyPoint(*kp, start, end, all_intersections, empty);
    }
  }
}

std::vector<std::vector<int>> getSplitLinePartCheckedIndexs(int start_index, int end_index, std::vector<std::vector<int>>& part_checked_lines) {
  std::vector<std::vector<int>> res;
  for (int i = start_index; i < end_index; i++) {
    for (auto& line_indexs : part_checked_lines) {
      if (i == line_indexs[0] && i + 1 == line_indexs[1]) {
        res.push_back({i - start_index, i + 1 - start_index});
        break;
      }
    }
  }
  return res;
}

std::vector<std::vector<int>> getPolygonSplitLinePartCheckedIndexs(int start_index, int end_index, std::vector<std::vector<int>>& part_checked_lines,
                                                                   int point_size) {
  std::vector<std::vector<int>> res;
  if (end_index == 0) {
    for (int i = start_index; i < point_size; i++) {
      for (auto& line_indexs : part_checked_lines) {
        int s = i;
        int e = (i + 1) % point_size;
        if (s == line_indexs[0] && e == line_indexs[1]) {
          int cs = s - start_index;
          int ce = e - start_index;
          if (ce <= 0) {
            ce = cs + 1;
          }
          res.push_back({cs, ce});
          break;
        }
      }
    }
  } else if (start_index >= end_index) {
    //说明首尾相连
    int off = point_size - start_index;
    int start_off = start_index;
    int before_size = 0;
    for (int i = start_index; i < point_size; i++) {
      for (auto& line_indexs : part_checked_lines) {
        int s = i;
        int e = (i + 1) % point_size;
        if (s == line_indexs[0] && e == line_indexs[1]) {
          int cs = s - start_off;
          int ce = e - start_off;
          if (ce <= 0) {
            ce = cs + 1;
          }
          res.push_back({cs, ce});
          break;
        }
      }
      before_size++;
    }
    if (start_index == 0 && end_index == 0) {
      end_index = point_size;
      before_size = 0;
    }
    for (int i = 0; i < end_index; i++) {
      for (auto& line_indexs : part_checked_lines) {
        int s = i;
        int e = (i + 1) % point_size;
        if (s == line_indexs[0] && e == line_indexs[1]) {
          res.push_back({s + off, e + off});
          break;
        }
      }
    }
  } else {
    for (int i = start_index; i < end_index; i++) {
      for (auto& line_indexs : part_checked_lines) {
        if (i == line_indexs[0] && i + 1 == line_indexs[1]) {
          res.push_back({i - start_index, i + 1 - start_index});
          break;
        }
      }
    }
  }

  return res;
}

void clearNodeCheckedData(ClippingData& global, entt::entity node) {
  for (auto obj : global.overall_selected_nodes) {
    if (obj == node) {
      // LayoutCtrlData::cancelSelectedElement(obj);  //清除整体选中高亮
    }
  }
  for (auto& obj : global.part_selected_nodes) {
    if (obj.node == node) {
      // LayoutCtrlData::cancelSelectedPointLine(obj); //清除部分选中高亮
    }
  }
}

void doClippingPath(ClippingData& global, ClippingNode& clipping_node, qlib::Path::s_ptr path_node, std::vector<ClippingInfo>& clipping_data,
                    undoRedoT::UndoRedoModule& undoRedoModule) {
  std::vector<qlib::Vec2d> origin_points = path_node->spine.points;  //要裁剪的线
  std::vector<std::vector<qlib::Vec2d>> result_paths;
  std::vector<qlib::Vec2d> current_line_points;
  int max = origin_points.size() - 1;
  bool berfor_line_record = false;
  for (size_t i = 0; i < max; ++i) {
    int start = i;
    int end = i + 1;
    auto it = std::find_if(clipping_data.begin(), clipping_data.end(), [start](const ClippingInfo& e) { return e.line_num == start; });
    current_line_points.push_back(origin_points[start]);
    //判断线段是否存在裁切
    if (it != clipping_data.end()) {
      if (it->clipping_all && !current_line_points.empty()) {
        if (current_line_points.size() > 1) {
          result_paths.push_back(current_line_points);  //保存上一段线
        }
        current_line_points.clear();
      } else {
        current_line_points.push_back(it->start_pos);
        result_paths.push_back(current_line_points);  //保存上一段线
        current_line_points.clear();
        current_line_points.push_back(it->end_pos);
        if (end == max && origin_points[end] != it->end_pos) {
          current_line_points.push_back(origin_points[end]);
          result_paths.push_back(current_line_points);  //扫描到末尾
        }
      }
    } else {
      current_line_points.push_back(origin_points[end]);
      if (end == max) {
        result_paths.push_back(current_line_points);  //扫描到末尾
      }
    }
  }

  std::vector<std::vector<qlib::Vec2d>> result_valid_paths;
  for (auto& path_array : result_paths) {
    if (path_array.size() > 1 && !arrayAllEqual(path_array)) {
      result_valid_paths.push_back(path_array);
    }
  }
  bool selected = elementIsSelected(global, clipping_node);
  //修改文件数据
  auto& reg = global.current_cell->reg;
  // undoRedoModule.start(global.current_cell);
  for (auto path_array : result_valid_paths) {
    qlib::Path::s_ptr path = qlib::Path::create();
    path->spine.points = Extension::filterDuplicatesPoints(path_array);
    path->layer = path_node->layer;
    entt::entity entity = global.layout_cmd.add(path);
    undoRedoModule.add(entity);
    if (selected) {
      //自动选中 对象标记为选中
      global.need_overa_all_checked_datas.push_back(entity);
    }
  }
  undoRedoModule.dele(clipping_node.node);
  global.layout_cmd.remove(clipping_node.node);
  global.removes.push_back(clipping_node.node);
}

std::vector<qlib::Vec2d> getPathValidPoints(std::vector<qlib::Vec2d>& points) {
  //重叠的点移除
  auto path = qlib::Path::create();
  path->spine.points = points;
  path->remove_overlapping_points();
  return path->spine.points;
}

void clippingPolygonWithTarget(ClippingData& global, ClippingNode& clipping_node, qlib::Polygon::s_ptr polygon_node,
                               std::vector<SplitLineInfo>& split_lines, bool remove_all, std::vector<std::vector<int>> part_checked_lines,
                               int points_size, undoRedoT::UndoRedoModule& undoRedoModule) {
  auto& reg = global.current_cell->reg;
  // undoRedoModule.start(global.current_cell);
  if (!remove_all) {
    std::vector<std::vector<qlib::Vec2d>> result_paths;
    std::vector<qlib::Vec2d> current_line_points;
    bool is_part_checked = !part_checked_lines.empty();
    std::vector<std::vector<std::vector<int>>> lines_parted_checked_indexs;
    int start_index = split_lines[0].start;
    // int start_index = split_lines[split_lines.size() - 1].end;  //起点索引为最后一根线的
    int end_index = split_lines[0].end;
    int i = 0;
    bool same_before_line = false;
    bool same_next_line = false;
    int split_size = split_lines.size();
    int before_start = split_lines[split_size - 1].start;
    int before_end = split_lines[split_size - 1].end;
    bool before_removed = false;

    for (auto& split_line_info : split_lines) {
      same_before_line = split_line_info.start == before_start && split_line_info.end == before_end;
      same_next_line = split_lines[(i + 1) % split_size].start == split_line_info.start;  //和下一条线起点相同
      if (split_line_info.need_remove) {
        result_paths.push_back(current_line_points);  //保存上一段线
        current_line_points.clear();
        std::vector<std::vector<int>> split_line_part_checked_indexs;
        lines_parted_checked_indexs.push_back(
            getPolygonSplitLinePartCheckedIndexs(start_index, end_index, part_checked_lines, points_size));  //保存上一段线的部分选择索引信息
        start_index = same_next_line ? split_line_info.start : split_line_info.end;
        if (same_before_line && i < split_lines.size() - 1 && split_lines[i + 1].start != split_line_info.start) {  //删除同一条线段的最后一段
          start_index = split_line_info.end;
        }
      } else {
        if (before_removed && start_index > split_line_info.start) {
          start_index = split_line_info.start;
        }
        end_index = split_line_info.end;
        if (split_line_info.head_is_inters && !before_removed) {
          split_line_info.points.erase(split_line_info.points.begin());  //删除第一个交点
        }
        if (split_line_info.end_is_inters && i < split_lines.size() - 1 && !split_lines[i + 1].need_remove) {
          split_line_info.points.pop_back();  //删除最后一个交点
        }
        current_line_points.insert(current_line_points.end(), split_line_info.points.begin(), split_line_info.points.end());
      }
      before_start = split_line_info.start;
      before_end = split_line_info.end;
      before_removed = split_line_info.need_remove;
      i++;
    }
    if (current_line_points.size() > 0) {
      //先判断首位是否相连
      if (!split_lines[0].need_remove && !split_lines[split_size - 1].need_remove) {
        std::reverse(current_line_points.begin(), current_line_points.end());  //逆转顺序 合并首尾
        result_paths[0].insert(result_paths[0].begin(), current_line_points.rbegin(), current_line_points.rend());
        auto& first_checked_indexs = lines_parted_checked_indexs[0];
        std::vector<std::vector<int>> checked_indexs = getPolygonSplitLinePartCheckedIndexs(start_index, end_index, part_checked_lines, points_size);
        auto valid_points = getPathValidPoints(current_line_points);
        int move_size = valid_points.size() - 1;
        for (auto& indexs : first_checked_indexs) {
          indexs[0] += move_size;  //往后顺移
          indexs[1] += move_size;
        }
        std::reverse(checked_indexs.begin(), checked_indexs.end());  //逆转顺序 合并首尾选中索引
        first_checked_indexs.insert(first_checked_indexs.begin(), checked_indexs.rbegin(), checked_indexs.rend());
      } else {
        result_paths.push_back(current_line_points);
        lines_parted_checked_indexs.push_back(
            getPolygonSplitLinePartCheckedIndexs(start_index, end_index, part_checked_lines, points_size));  //保存上一段线的部分选择索引信息
      }
    }
    std::vector<std::vector<qlib::Vec2d>> result_valid_paths;
    std::vector<std::vector<std::vector<int>>> valid_lines_parted_checked_indexs;
    i = 0;
    for (auto& path_array : result_paths) {
      if (path_array.size() > 1 && !arrayAllEqual(path_array)) {
        result_valid_paths.push_back(path_array);
        valid_lines_parted_checked_indexs.push_back(lines_parted_checked_indexs[i]);
      }
      i++;
    }
    bool selected = elementIsSelected(global, clipping_node);
    //修改文件数据
    i = 0;
    for (auto path_array : result_valid_paths) {
      qlib::Path::s_ptr path = qlib::Path::create();
      path->spine.points = Extension::filterDuplicatesPoints(path_array);
      path->layer = polygon_node->layer;
      entt::entity entity = global.layout_cmd.add(path);
      undoRedoModule.add(entity);  //添加修剪后的结果
      if (selected) {
        global.need_overa_all_checked_datas.push_back(entity);  //整体选择
      } else if (is_part_checked) {
        auto part_checked_lines = valid_lines_parted_checked_indexs[i];
        if (!part_checked_lines.empty()) {
          for (auto line_index : part_checked_lines) {
            global.need_part_checked_datas.push_back(PartCheckedInfo(line_index, entity));  //部分选择
          }
        }
      }
      i++;
    }

    // auto polygons = polygon_node->getGdsPolygon();
    // int layer = polygons[0]->m_layer;
    // std::vector<EelementNode*> eles = {temp_line};
    // i = 0;
    // for (auto path_array : result_valid_paths) {
    //   auto copy_ele = copyElement(eles);
    //   dynamic_cast<LineNode*>(copy_ele[0].get())->m_flexpath->m_point_array = path_array;
    //   dynamic_cast<LineNode*>(copy_ele[0].get())->m_flexpath->m_elements[0].m_layer = layer;
    //   dynamic_cast<LineNode*>(copy_ele[0].get())->update();
    //   QEDA_Internals::getInstance()->addPolygon(current_cell, copy_ele[0]->m_graph); //添加修剪后的结果
    //   if (selected) {
    //     need_overa_all_checked_datas.push_back(copy_ele[0]->m_graph); //整体选择
    //   } else if (is_part_checked) {
    //     auto part_checked_lines = valid_lines_parted_checked_indexs[i];
    //     if (!part_checked_lines.empty()) {
    //       for (auto line_index : part_checked_lines) {
    //         need_part_checked_datas.push_back(PartCheckedInfo(line_index, copy_ele[0]->m_graph)); //部分选择
    //       }
    //     }
    //   }
    //   i++;
    // }
  }
  // QEDA_Internals::getInstance()->removePolygon(current_cell, polygon_node->m_graph); //删除被修剪数据
  // clearNodeCheckedData(polygon_node);
  undoRedoModule.dele(clipping_node.node);
  global.layout_cmd.remove(clipping_node.node);
  global.removes.push_back(clipping_node.node);
  // undoRedoModule.end();
}

//裁剪多边形
void clippingPolygonByData(ClippingData& global, ClippingNode& clipping_node, qlib::Polygon::s_ptr polygon_node,
                           std::vector<ClippingInfo>& clipping_data, bool& is_elippse, undoRedoT::UndoRedoModule& undoRedoModule) {
  int layer = polygon_node->layer;
  std::vector<qlib::Vec2d> origin_points = polygon_node->points;  //要裁剪的多边形
  std::vector<std::vector<qlib::Vec2d>> result_paths;
  std::vector<qlib::Vec2d> current_line_points;
  int max = 0;
  int numVertices = origin_points.size();
  bool berfor_line_record = false;
  bool first_line_removed = false;
  if (is_elippse && clipping_data.empty()) {
    //删除整个圆
  } else {
    for (size_t i = 0; i < numVertices; ++i) {
      int start = i;
      int end = (i + 1) % numVertices;
      auto it = std::find_if(clipping_data.begin(), clipping_data.end(), [start](const ClippingInfo& e) { return e.line_num == start; });
      current_line_points.push_back(origin_points[start]);
      //判断线段是否存在裁切
      if (it != clipping_data.end()) {
        if (start == 0)
          first_line_removed = true;  //标记第一段线被修剪
        if (it->clipping_all && !current_line_points.empty()) {
          if (current_line_points.size() > 1) {
            result_paths.push_back(current_line_points);  //保存上一段线
          }
          current_line_points.clear();
        } else {
          current_line_points.push_back(it->start_pos);
          result_paths.push_back(current_line_points);  //保存上一段线
          current_line_points.clear();
          current_line_points.push_back(it->end_pos);
          if (end == max && origin_points[end] != it->end_pos) {
            current_line_points.push_back(origin_points[end]);
            if (first_line_removed) {
              result_paths.push_back(current_line_points);  //扫描到末尾
            } else {
              auto& first_line_array = result_paths[0];
              std::reverse(current_line_points.begin(), current_line_points.end());  //逆转顺序
              first_line_array.insert(first_line_array.begin(), current_line_points.rbegin(), current_line_points.rend());
            }
          }
        }
      } else {
        current_line_points.push_back(origin_points[end]);
        if (end == max) {
          if (first_line_removed) {
            result_paths.push_back(current_line_points);  //扫描到末尾
          } else {
            auto& first_line_array = result_paths[0];
            std::reverse(current_line_points.begin(), current_line_points.end());  //逆转顺序
            first_line_array.insert(first_line_array.begin(), current_line_points.rbegin(), current_line_points.rend());
          }
        }
      }
    }
  }

  std::vector<std::vector<qlib::Vec2d>> result_valid_paths;
  for (auto& path_array : result_paths) {
    if (path_array.size() > 1 && !arrayAllEqual(path_array)) {
      result_valid_paths.push_back(path_array);
    }
  }
  bool selected = elementIsSelected(global, clipping_node);
  //修改文件数据
  auto& reg = global.current_cell->reg;
  // undoRedoModule.start(global.current_cell);
  for (auto path_points_array : result_valid_paths) {
    qlib::Path::s_ptr path = qlib::Path::create();
    path->spine.points = Extension::filterDuplicatesPoints(path_points_array);
    path->layer = polygon_node->layer;
    entt::entity entity = global.layout_cmd.add(path);
    undoRedoModule.add(entity);
    if (selected) {
      //自动选中
      global.need_overa_all_checked_datas.push_back(entity);
    }
  }
  undoRedoModule.dele(clipping_node.node);
  global.layout_cmd.remove(clipping_node.node);
  global.removes.push_back(clipping_node.node);
  // undoRedoModule.end();

  // std::vector<EelementNode*> eles = {temp_line};
  // for (auto path_array : result_valid_paths) {
  //   auto copy_ele = copyElement(eles);
  //   dynamic_cast<LineNode*>(copy_ele[0].get())->m_flexpath->m_point_array = path_array;
  //   dynamic_cast<LineNode*>(copy_ele[0].get())->m_flexpath->m_elements[0].m_layer = layer;
  //   dynamic_cast<LineNode*>(copy_ele[0].get())->update();
  //   QEDA_Internals::getInstance()->addPolygon(current_cell, copy_ele[0]->m_graph); //添加修剪结果
  //   if (selected) {
  //     need_overa_all_checked_datas.push_back(copy_ele[0]->m_graph); //整体高亮
  //   }
  // }
  // QEDA_Internals::getInstance()->removePolygon(current_cell, polygon_node->m_graph); //删除图形
}

void doClippingPathWithTarget(ClippingData& global, ClippingNode& clipping_node, qlib::Path::s_ptr path_node, std::vector<SplitLineInfo>& split_lines,
                              bool remove_all, std::vector<std::vector<int>>& part_checked_lines, std::vector<int>& part_check_indxs,
                              undoRedoT::UndoRedoModule& undoRedoModule) {
  //修改文件数据
  auto& reg = global.current_cell->reg;
  // undoRedoModule.start(global.current_cell);
  if (!remove_all) {
    bool selected = elementIsSelected(global, clipping_node);
    bool is_part_checked = !part_checked_lines.empty();
    std::vector<std::vector<qlib::Vec2d>> result_paths;
    std::vector<std::vector<std::vector<int>>> lines_parted_checked_indexs;
    std::vector<qlib::Vec2d> current_line_points;
    int start_index = split_lines[0].start;
    int end_index = split_lines[0].end;
    int i = 0;
    bool same_before_line = false;
    bool same_next_line = false;
    int before_start = -1;
    int before_end = -1;
    bool before_removed = false;
    for (auto& split_line_info : split_lines) {
      same_before_line = split_line_info.start == before_start && split_line_info.end == before_end;  //和上一条线起点相同
      same_next_line = i < split_lines.size() - 1 &&
                       (split_lines[i + 1].start == split_line_info.start || split_lines[i + 1].end == split_line_info.end);  //和下一条线起点相同
      if (split_line_info.need_remove) {
        result_paths.push_back(current_line_points);  //保存上一段线
        current_line_points.clear();
        std::vector<std::vector<int>> split_line_part_checked_indexs;
        lines_parted_checked_indexs.push_back(
            getSplitLinePartCheckedIndexs(start_index, end_index, part_checked_lines));  //保存上一段线的部分选择索引信息
        start_index = same_next_line ? split_line_info.start : split_line_info.end;
        if (same_before_line && i < split_lines.size() - 1 && split_lines[i + 1].start != split_line_info.start) {  //删除同一条线段的最后一段
          start_index = split_line_info.end;
        }
      } else {
        end_index = split_line_info.end;
        if (split_line_info.head_is_inters && !before_removed) {
          split_line_info.points.erase(split_line_info.points.begin());  //删除第一个交点
        }
        if (split_line_info.end_is_inters && i < split_lines.size() - 1 && !split_lines[i + 1].need_remove) {
          split_line_info.points.pop_back();  //删除最后一个交点
        }
        current_line_points.insert(current_line_points.end(), split_line_info.points.begin(), split_line_info.points.end());
      }
      before_start = split_line_info.start;
      before_end = split_line_info.end;
      before_removed = split_line_info.need_remove;
      i++;
    }
    if (current_line_points.size() > 0) {
      result_paths.push_back(current_line_points);
      lines_parted_checked_indexs.push_back(
          getSplitLinePartCheckedIndexs(start_index, end_index, part_checked_lines));  //保存上一段线的部分选择索引信息
    }
    std::vector<std::vector<qlib::Vec2d>> result_valid_paths;
    std::vector<std::vector<std::vector<int>>> valid_lines_parted_checked_indexs;
    i = 0;
    for (auto& path_array : result_paths) {
      if (path_array.size() > 1 && !arrayAllEqual(path_array)) {
        result_valid_paths.push_back(path_array);
        valid_lines_parted_checked_indexs.push_back(lines_parted_checked_indexs[i]);
      }
      i++;
    }

    i = 0;
    for (auto path_array : result_valid_paths) {
      qlib::Path::s_ptr path = qlib::Path::create();
      path->spine.points = Extension::filterDuplicatesPoints(path_array);
      path->layer = path_node->layer;
      entt::entity entity = global.layout_cmd.add(path);
      undoRedoModule.add(entity);  //添加线
      if (selected) {
        global.need_overa_all_checked_datas.push_back(entity);  //整体选中高亮对象
      } else if (is_part_checked) {
        auto part_checked_lines = valid_lines_parted_checked_indexs[i];
        if (!part_checked_lines.empty()) {
          for (auto line_index : part_checked_lines) {
            global.need_part_checked_datas.push_back(PartCheckedInfo(line_index, entity));  //部分选中高亮对象
          }
        }
      }
      i++;
    }

    // std::vector<EelementNode*> eles = {path_node};
    // i = 0;
    // for (auto path_array : result_valid_paths) {
    //   auto copy_ele = copyElement(eles);
    //   dynamic_cast<LineNode*>(copy_ele[0].get())->m_flexpath->m_point_array = path_array;
    //   dynamic_cast<LineNode*>(copy_ele[0].get())->update();
    //   QEDA_Internals::getInstance()->addPolygon(current_cell, copy_ele[0]->m_graph); //添加线
    //   if (selected) {
    //     need_overa_all_checked_datas.push_back(copy_ele[0]->m_graph); //整体选中高亮对象
    //   } else if (is_part_checked) {
    //     auto part_checked_lines = valid_lines_parted_checked_indexs[i];
    //     if (!part_checked_lines.empty()) {
    //       for (auto line_index : part_checked_lines) {
    //         global.need_part_checked_datas.push_back(PartCheckedInfo(line_index, copy_ele[0]->m_graph)); //部分选中高亮对象
    //       }
    //     }
    //   }
    //   i++;
    // }
  }
  // QEDA_Internals::getInstance()->removePolygon(current_cell, path_node->m_graph); //删除线
  // clearNodeCheckedData(global, clipping_node.node);
  undoRedoModule.dele(clipping_node.node);
  global.layout_cmd.remove(clipping_node.node);
  global.removes.push_back(clipping_node.node);
  // undoRedoModule.end();
}

void doClippingLine(ClippingData& global, ClippingNode clipping_node, qlib::Path::s_ptr path_node, std::vector<std::vector<int>>& picked_lines_index,
                    std::vector<qlib::Vec2d>& hit_points, std::vector<qlib::Vec2d>& clipping_inters,
                    std::vector<std::vector<qlib::Vec2d>>& clipping_display_lines, bool& data_changed, bool process_extend,
                    undoRedoT::UndoRedoModule& undoRedoModule) {
  bool path_is_checked = elementIsSelected(global, clipping_node);
  bool path_is_part_checked = elementIsPartSelected(global, clipping_node);
  std::vector<std::vector<int>> part_checked_lines;
  std::vector<int> part_checked_indexs;
  if (path_is_part_checked) {
    getPartCheckedLines(global, clipping_node, part_checked_lines);
    getPartCheckedIndexs(global, clipping_node, part_checked_indexs);
  }
  // auto target_path = path_node->m_flexpath;
  std::vector<ClippingInfo> clipping_data;  //每条线段裁剪的信息 和所有对象求交
  std::vector<SplitLineInfo> split_lines;   //线被整体分解后的信息 和选中对象求交分解
  bool remove_all = false;                  //删除整个线
  std::vector<qlib::Vec2d> points = path_node->spine.points;
  // int picked_lines_index[1][2] = {{0, 1}};  //要裁切线段的索引
  std::vector<std::vector<qlib::Vec2d>> line_all_intersections;
  bool inster_with_all = global.overall_selected_nodes.empty() && global.part_selected_nodes.empty();
  if (inster_with_all || path_is_checked) {
    int i = 0;
    for (auto line_index : picked_lines_index) {
      qlib::Vec2d hit_point = hit_points[i];       //命中交点
      std::vector<qlib::Vec2d> all_intersections;  //所有交点
      int start_index = line_index[0];             //裁切线起点索引
      int end_index = line_index[1];               //裁切线终点索引
      qlib::Vec2d start = points[start_index];
      qlib::Vec2d end = points[end_index];
      if (path_is_checked) {
        //整体选中对象以线段为单位截断
        intersectWithPickedElements(global, path_node, start, end, start_index, end_index,
                                    all_intersections);  //与选中的可交对象求交点
      } else {
        intersectWithAll(global, path_node, start, end, start_index, end_index, all_intersections);  //与所有图形求交点
      }
      all_intersections = uniqueSortedPoints(all_intersections, start);
      line_all_intersections.push_back(all_intersections);
      for (auto pos : all_intersections) {
        clipping_inters.push_back(pos);
      }

      //存在交点
      if (!all_intersections.empty()) {
        std::vector<qlib::Vec2d> clipping_segment = findNearestSegment(start, end, all_intersections, hit_point);  //要剪掉的部分
        clipping_display_lines.push_back(clipping_segment);
        clipping_data.push_back(ClippingInfo(start_index, false, clipping_segment[0], clipping_segment[1]));
      } else {
        std::vector<qlib::Vec2d> clipping_segment = {start, end};
        clipping_display_lines.push_back(clipping_segment);
        qlib::Vec2d empty;
        clipping_data.push_back(ClippingInfo(start_index, true, empty, empty));
      }
      i++;
    }
  } else {
    bool exist_inter = false;                           //线和选中对象存在交点
    std::vector<SegmentInterInfo> segment_inter_infos;  //所有线段的相交信息
    if (path_is_part_checked) {
      std::vector<std::vector<int>> checked_lines_index = getElementPartSelectIndexs(global, clipping_node.node);  //选中线的索引
      getPathParCheckedSplitLines(global, path_node, points, checked_lines_index, split_lines, clipping_inters,
                                  exist_inter);  //分解线 先部分选择分解->再通过交点分解
      exist_inter = true;
    } else {
      getPathSplitLines(global, path_node, points, split_lines, clipping_inters, exist_inter, 0);  //分解线
    }

    //和目标对象求交显示要裁切线 把线当做整体裁切

    if (exist_inter) {
      int i = 0;
      for (auto line_index : picked_lines_index) {
        qlib::Vec2d hit_point = hit_points[i];                                                //命中交点
        clipping_display_lines.push_back(getClippingLineWithTarget(split_lines, hit_point));  //单击裁剪图形的一个部分
        i++;
      }
    } else {
      clipping_display_lines.push_back(points);  //没有交点剪掉所有
      remove_all = true;
    }
  }

  if (process_extend) {
    if (inster_with_all || path_is_checked) {
      doClippingPath(global, clipping_node, path_node, clipping_data, undoRedoModule);  //执行裁剪操作
    } else {
      doClippingPathWithTarget(global, clipping_node, path_node, split_lines, remove_all, part_checked_lines, part_checked_indexs,
                               undoRedoModule);  //执行和选中对象对比的裁剪操作
    }
    data_changed = true;
  }
}

void doClippingPolygon(ClippingData& global, ClippingNode clipping_node, qlib::Polygon::s_ptr target_polygon,
                       std::vector<std::vector<int>>& picked_lines_index, std::vector<qlib::Vec2d>& hit_points,
                       std::vector<qlib::Vec2d>& clipping_inters, std::vector<std::vector<qlib::Vec2d>>& clipping_display_lines, bool& data_changed,
                       bool process_clipping, undoRedoT::UndoRedoModule& undoRedoModule) {
  bool polygon_is_checked = elementIsSelected(global, clipping_node);
  bool polygon_is_part_checked = elementIsPartSelected(global, clipping_node);
  std::vector<std::vector<int>> part_checked_lines;
  std::vector<int> part_checked_indexs;
  if (polygon_is_part_checked) {
    getPartCheckedLines(global, clipping_node, part_checked_lines);
    getPartCheckedIndexs(global, clipping_node, part_checked_indexs);
  }

  std::vector<ClippingInfo> clipping_data;  //每条线段裁剪的信息 和所有对象求交
  std::vector<SplitLineInfo> split_lines;   //线被整体分解后的信息 和选中对象求交分解
  bool remove_all = false;                  //删除整个多边形
  std::vector<qlib::Vec2d> points = target_polygon->points;
  std::vector<qlib::Vec2d> polygon_all_intersections;
  int points_size = points.size();
  bool inster_with_all = global.overall_selected_nodes.empty() && global.part_selected_nodes.empty();

  auto el = clipping_node.node;
  auto& reg = global.current_cell->reg;
  auto is_elippse = reg.try_get<qlib::Ellipse::s_ptr>(el);  //判断圆形
  auto is_fan = reg.try_get<qlib::Fan::s_ptr>(el);          //判断扇形

  if (inster_with_all || polygon_is_checked) {
    if (is_elippse || is_fan) {
      bool exist_inter = false;
      int before_ins_size = clipping_inters.size();
      getPolygonSplitLines(global, clipping_node.node, target_polygon, points, split_lines, clipping_inters, exist_inter,
                           !polygon_is_checked);                    //分解圆
      int all_ins_size = clipping_inters.size() - before_ins_size;  //和圆的所有交点数量
      //和目标对象求交显示要裁切线 把线当做整体裁切
      if (clipping_inters.size() == 2 && arePointsEqual(clipping_inters[0], clipping_inters[1])) {
        clipping_inters.erase(clipping_inters.begin());  //bug6384 当多边形的一个点在选中直线上，需要去重
      }
      if (all_ins_size > 1) {
        int i = 0;  //1个以上交点做修剪判断
        for (auto line_index : picked_lines_index) {
          qlib::Vec2d hit_point = hit_points[i];                                                //命中交点
          clipping_display_lines.push_back(getClippingLineWithTarget(split_lines, hit_point));  //单击裁剪图形的一个部分
          i++;
        }
      }
      if (all_ins_size == 1) {
        return;
      }
      if (all_ins_size == 0) {
        std::vector<qlib::Vec2d> polygon_line = points;
        polygon_line.push_back(polygon_line[0]);
        clipping_display_lines.push_back(polygon_line);  //没有交点修剪掉所有
        remove_all = true;
      }
    } else {
      int i = 0;
      for (auto line_index : picked_lines_index) {
        qlib::Vec2d hit_point = hit_points[i];       //命中交点
        std::vector<qlib::Vec2d> all_intersections;  //所有交点
        int start_index = line_index[0];             //裁切线起点索引
        int end_index = line_index[1];               //裁切线终点索引
        qlib::Vec2d start = points[start_index];
        qlib::Vec2d end = points[end_index];
        if (polygon_is_checked) {
          //整体选中对象以线段为单位截断
          intersectPolygonWithPickedElements(global, clipping_node.node, target_polygon, start, end, start_index, end_index,
                                             all_intersections);  //与选中的可交对象求交点
        } else {
          intersectPolygonWithAll(global, clipping_node.node, target_polygon, start, end, start_index, end_index,
                                  all_intersections);  //与所有图形求交点
        }
        all_intersections = uniqueSortedPoints(all_intersections, start);
        polygon_all_intersections.insert(polygon_all_intersections.end(), all_intersections.begin(),
                                         all_intersections.end());  //记录多边形所有交点
        for (auto pos : all_intersections) {
          clipping_inters.push_back(pos);
        }

        //存在交点
        if (!all_intersections.empty()) {
          std::vector<qlib::Vec2d> clipping_segment = findNearestSegment(start, end, all_intersections, hit_point);  //要剪掉的部分
          clipping_display_lines.push_back(clipping_segment);
          clipping_data.push_back(ClippingInfo(start_index, false, clipping_segment[0], clipping_segment[1]));
        } else {
          std::vector<qlib::Vec2d> clipping_segment = {start, end};
          clipping_display_lines.push_back(clipping_segment);
          qlib::Vec2d empty;
          clipping_data.push_back(ClippingInfo(start_index, true, empty, empty));
        }
        i++;
      }
    }

  } else {
    bool exist_inter = false;                           //多边形和选中对象存在交点
    std::vector<SegmentInterInfo> segment_inter_infos;  //所有线段的相交信息
    int before_ins_size = clipping_inters.size();
    if (polygon_is_part_checked) {
      std::vector<std::vector<int>> checked_lines_index = getElementPartSelectIndexs(global, clipping_node.node);  //选中多边形的索引
      getPolygonParCheckedSplitLines(global, clipping_node.node, target_polygon, points, checked_lines_index, split_lines, clipping_inters,
                                     exist_inter);  //分解多边形 先部分选择分解->再通过交点分解
      exist_inter = true;
    } else {
      getPolygonSplitLines(global, clipping_node.node, target_polygon, points, split_lines, clipping_inters, exist_inter, false);  //分解线
    }
    if (clipping_inters.size() == 2 && arePointsEqual(clipping_inters[0], clipping_inters[1])) {
      clipping_inters.erase(clipping_inters.begin());  //bug6384 当多边形的一个点在选中直线上，需要去重
    }
    if (polygon_is_part_checked) {
      if (exist_inter && !is_elippse) {
        int i = 0;
        for (auto line_index : picked_lines_index) {
          qlib::Vec2d hit_point = hit_points[i];                                                //命中交点
          clipping_display_lines.push_back(getClippingLineWithTarget(split_lines, hit_point));  //单击裁剪图形的一个部分
          i++;
        }
      } else {
        clipping_display_lines.push_back(points);  //没有交点剪掉所有
        remove_all = true;
      }
    } else {
      int all_ins_size = clipping_inters.size() - before_ins_size;  //和多边形的所有交点数量
      //和目标对象求交显示要裁切线 把线当做整体裁切
      if (all_ins_size > 1) {
        int i = 0;  //1个以上交点做修剪判断
        for (auto line_index : picked_lines_index) {
          qlib::Vec2d hit_point = hit_points[i];                                                //命中交点
          clipping_display_lines.push_back(getClippingLineWithTarget(split_lines, hit_point));  //单击裁剪图形的一个部分
          i++;
        }
      }
      if (all_ins_size == 1) {
        return;
      }
      if (all_ins_size == 0) {
        std::vector<qlib::Vec2d> polygon_line = points;
        polygon_line.push_back(polygon_line[0]);
        clipping_display_lines.push_back(polygon_line);  //没有交点修剪掉所有
        remove_all = true;
      }
    }
  }

  if (process_clipping) {
    if (inster_with_all || polygon_is_checked) {
      if (is_elippse || is_fan) {
        part_checked_lines.clear();  //排除部分选择的圆
        clippingPolygonWithTarget(global, clipping_node, target_polygon, split_lines, remove_all, part_checked_lines, points_size,
                                  undoRedoModule);  //执行和选中对象对比的裁剪操作
      } else {
        bool is_elippse_bool = false;
        clippingPolygonByData(global, clipping_node, target_polygon, clipping_data, is_elippse_bool, undoRedoModule);  //执行裁剪操作
      }
    } else {
      clippingPolygonWithTarget(global, clipping_node, target_polygon, split_lines, remove_all, part_checked_lines, points_size,
                                undoRedoModule);  //执行和选中对象对比的裁剪操作
    }
    data_changed = true;
  }
}

//更新左下角信息
void updateClippingStatusBarInfo(ecs::Bus& bus, bool picked_lines, bool exist_clipping_lines, bool exist) {
  QString sendOperaterMessageInfo;
  if (!picked_lines) {
    sendOperaterMessageInfo = QObject::tr("Mode: Clipping | Select the object to be trimmed and hold down the space bar to extend the operation");
  } else {
    if (!exist_clipping_lines) {
      sendOperaterMessageInfo = QObject::tr("Mode: Clipping | The current object cannot be trimmed");
    } else {
      sendOperaterMessageInfo = QObject::tr("Mode: Clipping | The current object can be trimmed");
    }
  }
  if (exist) {
    sendOperaterMessageInfo = QObject::tr("");
  }
  bus.send<qbe::UiMessage::OperatorInfoMessage>(qbe::UiMessage::OperatorInfoMessage{sendOperaterMessageInfo});
}

bool elementIsVisible(long layer_num) {
  // std::vector<std::string> info = LayoutCtrlData::getLayerStyleInfoOnNum(layer_num);
  // return info[6] == "unhide";
  return true;
}

bool arePointsEqual(qlib::Vec2d a, qlib::Vec2d b) {
  float epsilon = 1e-3;  //精度范围内视为同一个点
  return (fabs(a.x - b.x) <= epsilon) && (fabs(a.y - b.y) <= epsilon);
}
}  // namespace qbe::editing::Clipping